/* Copyright (C) 2007 Free Software Foundation, Inc. 
 * See the copyright notice in the file /usr/LICENSE.
 * Created by flyan on 2020/5/25.
 * QQ: 1341662010
 * QQ-Group:909830414
 * gitee: https://gitee.com/flyanh/
 *
 * 7. 整数反转
 * 给出一个 32 位的有符号整数，你需要将这个整数中每位上的数字进行反转。
 *
 * 示例 1:
 *
 * 输入: 123
 * 输出: 321
 *  示例 2:
 *
 * 输入: -123
 * 输出: -321
 * 示例 3:
 *
 * 输入: 120
 * 输出: 21
 *
 * 注意:
 *
 * 假设我们的环境只能存储得下 32 位的有符号整数，则其数值范围为 [−231,  231 − 1]。请根据这个假设，如果反转后整数溢出那么就返回 0。
 */
#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <limits.h>

/* 无法满足以上的注意要求，因为使用了 long 类型。
 * 但是这个运行速度更块，计算量更少了～
 */
static int reverse1(int x){
    long tx = x;    /* 用 long 来防止正负数转换溢出 */
    long ans = 0;   /* 用 long 来判断溢出 */
    long pow;
    static int ans_buf[12];
    register int ans_buf_len = 0, i, j, k;

    /* 是否是负数？ */
    char negative = (char) (tx < 0);
    if(negative) tx = -tx;

    /* 将其反转得到每一位 */
    do {
        ans_buf[ans_buf_len++] = tx % 10u;
        tx /= 10u;
    } while (tx);

    /* 重新计算出十进制的值 */
    for(i = 0, j = ans_buf_len - 1; i < ans_buf_len; ++i, --j) {
        pow = ans_buf[i];
        for(k = j; k > 0; --k)
            pow *= 10;
        ans += pow;
    }
    /* 判断溢出否？ */
    if(ans > INT_MAX || ans < INT_MIN) return 0;

    if(negative) ans = -ans;    /* 如果是负数，我们恢复 */
    return (int) ans;
}

static int reverse(register int x){
    int ans = 0;
    /* 将其反转得到每一位 */
    do {
        /* 从小到大获取位上的值 */
        int pop = x % 10;
        x /= 10;
        /* 溢出否？ */
        if (ans > INT_MAX/10 || (ans == INT_MAX / 10 && pop > 7)) return 0;
        if (ans < INT_MIN/10 || (ans == INT_MIN / 10 && pop < -8)) return 0;
        /* 得出结果，反向的 */
        ans *= 10;
        ans += pop;
    } while (x);
    return (int) ans;
}

int main(void) {
//    int max = 2147483647;
    int i = 2147483647;
    printf("%d reverse: %d\n", i, reverse(i));

}

